package com.weixing.mall.provider.auth.member.xcx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.weixing.mall.base.utils.EnumUtil;
import com.weixing.mall.provider.enums.MsgFlagEnum;
import com.weixing.oauth2.common.userdetails.IUserAuthService;
import com.weixing.oauth2.common.userdetails.SecurityUser;
import lombok.Setter;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author mall
 */
@Setter
public class MemberXcxAuthenticationProvider implements AuthenticationProvider {
    private IUserAuthService userDetailService;
    private PasswordEncoder passwordEncoder;
    private WxMaService wxMaMemberService;

    @Override
    public Authentication authenticate(Authentication authentication) {
        MemberXcxAuthenticationToken authenticationToken = (MemberXcxAuthenticationToken) authentication;
        // openid
        String code = (String) authenticationToken.getPrincipal();
        String openid = null;
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaMemberService.getUserService().getSessionInfo(code);
            openid = sessionInfo.getOpenid();
        } catch (WxErrorException e) {
            throw new InternalAuthenticationServiceException("code 换取openid失败");
        }
        SecurityUser user = userDetailService.loadUserByXcxOpenId(openid);
        String msgFlag = user.getMsgFlag();
        if (!MsgFlagEnum.SUCCESS.getValue().equals(msgFlag)) {
            throw new InternalAuthenticationServiceException(EnumUtil.getDesp(MsgFlagEnum.class, msgFlag));
        }
        if (!user.isEnabled()){
            throw new DisabledException("该账户已禁用");
        }
        MemberXcxAuthenticationToken authenticationResult = new MemberXcxAuthenticationToken(user, user.getAuthorities());
        authenticationResult.setDetails(authenticationToken.getDetails());
        return authenticationResult;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return MemberXcxAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
